package com.htthorizon.model.service;

import java.util.*;

import cn.hutool.crypto.digest.MD5;
import com.htthorizon.common.core.constant.Constants;
import com.htthorizon.common.core.exception.ServiceException;
import com.htthorizon.common.core.utils.DateUtils;
import com.htthorizon.common.core.utils.StringUtils;
import com.htthorizon.common.security.utils.SecurityUtils;
import com.htthorizon.model.response.MetaDataDto;
import com.htthorizon.system.api.model.ModelInfoReq;
import com.htthorizon.util.DynamicCreateTableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.htthorizon.model.mapper.ModelMetaMapper;
import com.htthorizon.model.domain.ModelMeta;
import org.springframework.util.CollectionUtils;

/**
 * 模型的元数据信息Service业务层处理
 *
 * @author mark
 * @date 2023-11-16
 */
@Service
@Slf4j
public class ModelMetaServiceImpl implements IModelMetaService
{
    @Autowired
    private ModelMetaMapper modelMetaMapper;

    @Autowired
    private DynamicCreateTableUtil dynamicCreateTableUtil;

    /**
     * 查询模型的元数据信息
     *
     * @param id 模型的元数据信息主键
     * @return 模型的元数据信息
     */
    @Override
    public ModelMeta selectModelMetaById(Long id)
    {
        return modelMetaMapper.selectModelMetaById(id);
    }

    /**
     * 查询模型的元数据信息列表
     *
     * @param modelMeta 模型的元数据信息
     * @return 模型的元数据信息
     */
    @Override
    public List<ModelMeta> selectModelMetaList(ModelMeta modelMeta)
    {
        return modelMetaMapper.selectModelMetaList(modelMeta);
    }

    /**
     * 根据模型id查询模型的字段列表
     *
     * @param modelId 模型ID
     * @return 模型的元数据信息集合
     */
    @Override
    public Map<String,String> getModelFieldsByModelId(Long modelId){
        ModelMeta modelMeta = new ModelMeta();
        modelMeta.setModelId(modelId);
        List<ModelMeta> list = selectModelMetaList(modelMeta);
        if(!CollectionUtils.isEmpty(list)){
            Map<String,String> fieldMap = new HashMap<>(list.size());
            for (ModelMeta meta:list){
                fieldMap.put(meta.getMetaFieldName(),meta.getMetaFieldRemark());
            }
            return fieldMap;
        }
        return null;
    }
    @Override
    public Map<String,String> getModelFieldsByModelId2(Long modelId){
        ModelMeta modelMeta = new ModelMeta();
        modelMeta.setModelId(modelId);
        List<ModelMeta> list = selectModelMetaList(modelMeta);
        if(!CollectionUtils.isEmpty(list)){
            Map<String,String> fieldMap = new HashMap<>(list.size());
            for (ModelMeta meta:list){
                fieldMap.put(meta.getMetaFieldName(),meta.getMetaFieldType());
            }
            return fieldMap;
        }
        return null;
    }

    /**
     * 保存元数据信息
     * @param modelInfo
     * @param metaDataDtoList
     * @return
     */
    @Override
    public int saveModelMeta(ModelInfoReq modelInfo, List<MetaDataDto> metaDataDtoList){
        Long modelId = modelInfo.getId();
        int count = 0;
        //删除元数据,如果原有采集的元数据在新获取的元数据列表中不存在，则删除
        List<ModelMeta> modelMetaList = modelMetaMapper.getModelMetaList(modelId, null);
        if(modelMetaList != null && modelMetaList.size() > 0){
            for (ModelMeta modelMeta:modelMetaList){
                boolean exists = false;
                log.info("modelMeta : {}" , modelMeta);
                for (MetaDataDto metaDataDto:metaDataDtoList){
                    String s = Optional.ofNullable(modelMeta).map(ModelMeta::getMetaFieldName).orElse("");
                    if(s.equals(metaDataDto.getName())){
                        exists = true;
                        break;
                    }
                }
                if(!exists){
                    modelMeta.setUpdateTime(new Date());
                    modelMeta.setUpdateBy(SecurityUtils.getUsername());
                    modelMeta.setStatus(-1);
                    count += this.modelMetaMapper.updateModelMeta(modelMeta);
                }
            }
        }
        //新增、修改元数据
        for (int i=0; i< metaDataDtoList.size(); i++){
            MetaDataDto dto = metaDataDtoList.get(i);
            String metaFieldName = dto.getName();
            String metaFieldRemark = dto.getCol_comment();
            String metaFieldType = dto.getType();
            String metaCodeStr = StringUtils.joinWith("," , modelId, metaFieldName, metaFieldRemark, metaFieldType);
            String metaCodeMD5 = MD5.create().digestHex16(metaCodeStr);
            int metaVersion = 1;
            List<ModelMeta> metaList = modelMetaMapper.getModelMetaList(modelId, metaFieldName);
            //1查询元数据是否存在
            if(metaList != null && metaList.size() > 0){
                if(metaList.size() > 1){
                    throw new ServiceException("相同名称的元数据存在多个，查询元数据异常！");
                }
                //2如果存在，则对比其他属性信息，一致则跳过，不一致则更新为删除状态再新增一条数据
                ModelMeta oldMeta = metaList.get(0);
                if(metaCodeMD5.equals(oldMeta.getMetaCode())){
                    continue;
                }else {
                    oldMeta.setUpdateBy(SecurityUtils.getUsername());
                    oldMeta.setUpdateTime(new Date());
                    oldMeta.setStatus(-1);
                    count += this.modelMetaMapper.updateModelMeta(oldMeta);
                    //增加版本
                    metaVersion = metaVersion + oldMeta.getMetaVersion();
                }
            }
            //3插入新记录
            ModelMeta modelMeta = new ModelMeta();
            modelMeta.setMetaCode(metaCodeMD5);
            modelMeta.setSourceId(modelInfo.getSourceId());
            modelMeta.setMetaFieldName(metaFieldName);
            modelMeta.setMetaFieldRemark(metaFieldRemark);
            modelMeta.setMetaFieldType(metaFieldType);
            modelMeta.setModelName(dto.getModel_tb());
            modelMeta.setModelId(modelId);
            modelMeta.setModelName(modelInfo.getModelName());
            modelMeta.setMetaFieldSort(i+1);
            modelMeta.setMetaVersion(metaVersion);
            modelMeta.setCreateBy(SecurityUtils.getUsername());
            modelMeta.setCreateTime(new Date());
            modelMeta.setStatus(Constants.DELETE_STATUS_NO);
            count += this.modelMetaMapper.insertModelMeta(modelMeta);
        }
        return count;
    }

    /**
     * 新增模型的元数据信息
     *
     * @param modelMeta 模型的元数据信息
     * @return 结果
     */
    @Override
    public int insertModelMeta(ModelMeta modelMeta)
    {
        modelMeta.setCreateTime(DateUtils.getNowDate());
        modelMeta.setStatus(Constants.DELETE_STATUS_NO);
        modelMeta.setCreateBy(SecurityUtils.getUsername());
        return modelMetaMapper.insertModelMeta(modelMeta);
    }

    /**
     * 修改模型的元数据信息
     *
     * @param modelMeta 模型的元数据信息
     * @return 结果
     */
    @Override
    public int updateModelMeta(ModelMeta modelMeta)
    {
        modelMeta.setUpdateTime(DateUtils.getNowDate());
        modelMeta.setUpdateBy(SecurityUtils.getUsername());
        return modelMetaMapper.updateModelMeta(modelMeta);
    }

    /**
     * 批量删除模型的元数据信息
     *
     * @param ids 需要删除的模型的元数据信息主键
     * @return 结果
     */
    @Override
    public int deleteModelMetaByIds(Long[] ids)
    {
        return modelMetaMapper.deleteModelMetaByIds(ids);
    }

    /**
     * 删除模型的元数据信息信息
     *
     * @param id 模型的元数据信息主键
     * @return 结果
     */
    @Override
    public int deleteModelMetaById(Long id)
    {
        return modelMetaMapper.deleteModelMetaById(id);
    }

    // todo 判断表字段的版本 删除表待优化
    @Override
    public int createTableByTableName(String tableName,String tableNameZn) {
        try{
            modelMetaMapper.ifExistDropTable(tableName);
        }catch (Exception e){
            log.error("删除表: ",e);
        }

        List<ModelMeta> list=  this.selectModelMetaByTableName(tableName);

        String sql = dynamicCreateTableUtil.buildTableSql(tableName,tableNameZn, list);

        dynamicCreateTableUtil.executeSql(sql);

        return 0;
    }
    @Override
    public List<ModelMeta> selectModelMetaByTableName(String tableName){
        return modelMetaMapper.selectModelMetaByTableName(tableName);
    }


    @Override
    public int deleteModelMetaByTableName(String tableName) {

        return modelMetaMapper.deleteModelMetaByTableName(tableName);

    }

    @Override
    public String selectModelMetaByEnName(String key) {
        return modelMetaMapper.selectModelMetaByEnName(key);
    }
}
